package com.tulei.admin.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tulei.common.annotation.Log;
import com.tulei.common.constant.RedisConstant;
import com.tulei.common.response.R;
import com.tulei.common.response.TableDataInfo;
import com.tulei.common.utils.RedisUtils;
import com.tulei.common.utils.websocket.Message;
import com.tulei.system.Entity.Dto.Modle;
import com.tulei.system.Entity.Dto.TableDto;
import com.tulei.system.Entity.SysRole;
import com.tulei.system.Entity.SysUser;
import com.tulei.system.mapper.RoleMapper;
import com.tulei.system.mapper.UserMapper;
import com.tulei.system.service.MessageService;
import com.tulei.system.service.MovieService;
import com.tulei.system.service.RoleService;
import com.tulei.system.service.UserService;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author TuLei
 * @Date 2024-05-23 21:44
 **/


@RequiredArgsConstructor
@RestController
@RequestMapping("/api/user")
public class SysUserController {

    private final UserService userService;

    private final RedisUtils redisUtils;

    private final MessageService messageService;

    private final RoleService roleService;

    @Resource
    private RedissonClient redissonClient;

    @GetMapping("/info")
    public R<Map<String, Object>> info(){
        SysUser user = (SysUser) StpUtil.getSession().get("user");
        List<String> roles = StpUtil.getRoleList();
        HashMap<String, Object> map = new HashMap<>();
        map.put("roles",roles);
        map.put("avatar",user.getAvatar());
        map.put("name",user.getName());
        return R.ok(map);
    }

    @Log
    @GetMapping("/getList")
    @SaCheckPermission("user:add")
    public R<List<Modle>> list(){
//        StpUtil.getPermissionList();
//        StpUtil.getRoleList();

        List<Modle> modles = new ArrayList<>();
        RLock lock = redissonClient.getLock("myLock");
        int retryCount = 0;
        int maxRetries = 5; // 最大重试次数
        int retryInterval = 100; // 较短的重试间隔时间，单位毫秒，减少等待时间以提高响应性

        while (retryCount <= maxRetries) {
            // 尝试获取锁，这里不设置过期时间，因为一旦获取成功，看门狗会自动续期
            boolean isLocked = lock.tryLock();
            if (isLocked) {
                try {
                    // 成功获取锁，提示信息
                    modles = userService.getList();

                    // 这里模拟业务逻辑执行，实际上看门狗已经开始工作
                    try {
                        Thread.sleep(50000); // 模拟业务逻辑执行时间
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    break; // 退出循环
                } finally {
                    lock.unlock(); // 释放锁
                }
            } else {
                // 获取锁失败，打印信息，稍后重试
                System.out.println("锁已被占用，第 " + (retryCount + 1) + " 次尝试，稍后再试...");
                retryCount++;
                try {
                    Thread.sleep(retryInterval); // 短暂等待后重试
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        if (retryCount > maxRetries) {
            System.out.println("尝试获取锁超过最大重试次数，操作失败。");
        }
        return R.ok(modles);
    }

    @PostMapping("/del")
    @SaCheckPermission("user:update")
    public R<Void> add(@RequestBody SysUser sysUser){
        redisUtils.del(RedisConstant.perms + StpUtil.getLoginId());
        redisUtils.del(RedisConstant.roles + StpUtil.getLoginId());
        return R.ok();
    }




    @ResponseBody
    @ApiOperation("获取用户头像")
    @RequestMapping("/userImage")
    public R<byte[]> getUserImage() {
        String account = (String) StpUtil.getLoginId();
        return R.ok(userService.getUserImage(account));
    }

    @ResponseBody
    @RequestMapping("/getInfo")
    @ApiOperation("主页回显个人信息")
    public R<Map<String, Object>> getInfo() {
        Map<String, Object> info = userService.getInfo();
        return R.ok(info);
    }
    @PostMapping("/sendMsg")
    public R<Void> sendMsg(@RequestBody Message message) {
        messageService.sendMsg(message);
        return R.ok();
    }



    @GetMapping("/list")
    public TableDataInfo list(TableDto tableDto) {
        int pageNum = tableDto.getPageNum();
        int pageSize = tableDto.getPageSize();
        int offset = (pageNum - 1) * pageSize;
        List<SysUser> list = userService.selectList(tableDto,offset,pageSize);
        return TableDataInfo.ok(list);
    }


    @GetMapping(value = { "/", "/{userId}" })
    public R<Map<String, Object>> getInfo(@PathVariable(value = "userId", required = false) Long userId)
    {
        SysUser user = userService.getOne(new QueryWrapper<SysUser>().eq("user_id", userId));
        HashMap<String, Object> map = new HashMap<>();
        List<SysRole> roles = roleService.list();
        map.put("roles",roles);
        SysRole role = roleService.getRoleById(userId);
        List<Integer> roleIds = roles.stream()
                .filter(r -> r.getAccess() >= role.getAccess())
                .map(SysRole::getRoleId)
                .collect(Collectors.toList());
        map.put("roleIds",roleIds);
        map.put("user",user);
        return R.ok(map);
    }
}
